package com.hopedove.workshop.api

import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import com.hopedove.net.ApiCallResult
import com.hopedove.net.kotlin.ErrorResult
import com.hopedove.net.kotlin.SoapClient
import com.hopedove.net.kotlin.SuccessResult
import com.hopedove.workshop.data.pojo.ObservableTakeInventoryItem
import com.orhanobut.logger.Logger

@Suppress("SpellCheckingInspection")
class WorkshopApi(private val client: SoapClient = SoapClient()) {

    /**
     *  登录接口
     */
    suspend fun login(username: String, password: String): ApiCallResult<WorkshopLoginData> {
        val method = "machcotLogin"
        val params = JsonObject().apply {
            addProperty("YHM", username)
            addProperty("YHKL", password)
        }
        val result = client.makeCall(method, Gson().toJson(params))
        Logger.d("login: $result")

        return getApiResult(result, WorkshopLoginData::class.java)
    }

    /**
     *  换批确认获取列表接口
     *
     *  @param date 日期
     *  @param originPlace 原产地
     *  @param batchNo 换批号
     *  @param yarnNo 纱支号
     *  @param remark  备注
     */
    suspend fun exchangeBatchList(
        id: String,
        date: String,
        originPlace: String? = null,
        batchNo: String? = null,
        yarnNo: String? = null,
        remark: String? = null
    ): ApiCallResult<List<WorkshopExchangeBatchList>> {
        val method = "machcotCofList"
        val params = buildJsonParam {
            addProperty("XTYHID", id)
            addProperty("LISTDATE", date)
            addProperty("ORIPLACE", originPlace)
            addProperty("BATCHNO", batchNo)
            addProperty("SZQC", yarnNo)
            addProperty("REMARK", remark)
        }

        val result = client.makeCall(method, params)

        return getApiResult(result, object : TypeToken<List<WorkshopExchangeBatchList>>() {}.type)
    }


    /**
     *  换批确认接口
     */
    suspend fun exchangeBatchConfirm(
        id: String,
        account: String,
        primaryId: String
    ): ApiCallResult<String> {
        val method = "machcotConfirm"
        val params = JsonObject().apply {
            addProperty("XTYHID", id)
            addProperty("XM", account)
            addProperty("PKIDS", primaryId)
        }

        val result = client.makeCall(method, Gson().toJson(params))
        Logger.d("ExchangeBatchConfirm  $result")
        return getCommonApiResult(result)
    }

    /**
     *  换批确认 - 备注列表接口
     */
    suspend fun exchangeBatchRemarkList(id: String = "RYMSHPBZ"): ApiCallResult<List<ExchangeBatchRemark>> {
        val method = "querySJZDBySJZDID"
        val params = JsonObject().apply {
            addProperty("SJZDID", id)
        }

        val result = client.makeCall(method, Gson().toJson(params))
        Logger.d("login: $result")
        return getApiResult(result, object : TypeToken<List<ExchangeBatchRemark>>() {}.type)
    }


    /**
     *  运转情况 - 加载原料信息接口
     *
     */
    suspend fun runningSituationGetMaterials(machineNo: String): ApiCallResult<List<MaterialItem>> {
        val method = "operaCondYlbyMachineno"
        val params = JsonObject().apply {
            addProperty("MACHINENO", machineNo)
        }

        val result = client.makeCall(method, Gson().toJson(params))

        Logger.d("GetMaterials: $result")
        return getApiResult(result, object : TypeToken<List<MaterialItem>>() {}.type)
    }


    /**
     *  运转情况 - 添加条目
     *
     */
    suspend fun runningSitationAdd(
        id: String,
        account: String,
        list: List<RunningSituationAdd>
    ): ApiCallResult<String> {
        return runningSituationAddAndSave(
            id,
            account,
            WorkshopApiConstants.SAVE_TYPE_ADD,
            Gson().toJsonTree(list)
        )
    }

    /**
     *  运转情况 - 保存条目
     *
     */
    suspend fun runningSituationSave(
        id: String,
        account: String,
        list: List<RunningSituationSave>
    ): ApiCallResult<String> {
        return runningSituationAddAndSave(
            id,
            account,
            WorkshopApiConstants.SAVE_TYPE_SAVE,
            Gson().toJsonTree(list)
        )
    }

    /**
     *  运转情况 - 保存和添加接口
     *
     *  这个接口有两个功能，保存和添加
     */
    private suspend fun runningSituationAddAndSave(
        id: String,
        account: String,
        type: String,
        data: JsonElement
    ): ApiCallResult<String> {
        val method = "operaCondSave"

        val params = JsonObject().apply {
            addProperty("XTYHID", id)
            addProperty("XM", account)
            addProperty("TYPE", type)
            add("jsonData", data)
        }

        val result = client.makeCall(method, Gson().toJson(params))
        Logger.d("RunningSituationAddAndSave Request: ${Gson().toJson(params)}")
        Logger.d("RunningSituationAddAndSave Result: $result")
        return getCommonApiResult(result)
    }


    /**
     * 运转情况 - 查询列表接口
     *
     */
    suspend fun runningSituationQueryList(
        dateFrom: String,
        dateTo: String,
        machineNoFrom: String,
        machineNoTo: String,
        workshopId: String,
        type: String,
        planTypeCode: String,
    ): ApiCallResult<List<RunnningSituation>> {
        val method = "operaCondList"
        val params = JsonObject().apply {
            addProperty("CREATER", "")
            addProperty("LISTDATE_FROM", dateFrom)
            addProperty("LISTDATE_TO", dateTo)
            addProperty("MACHINENO_FROM", machineNoFrom)
            addProperty("MACHINENO_TO", machineNoTo)
            addProperty("LISTTYPE", type)
            addProperty("WORKSHOP", workshopId)
            addProperty("PLANTYPE", planTypeCode)
        }

        val result = client.makeCall(method, Gson().toJson(params))
        Logger.d("SituationQueryList  Request: ${Gson().toJson(params)}")
        Logger.d("SituationQueryList  Result: $result")
        return getApiResult(result, object : TypeToken<List<RunnningSituation>>() {}.type)
    }

    /**
     *  运转情况 - 删除接口
     */
    suspend fun runningSituationDelete(primaryId: String): ApiCallResult<String> {
        val method = "operaCondDel"
        val params = JsonObject().apply {
            addProperty("PKIDS", primaryId)
        }

        val result = client.makeCall(method, Gson().toJson(params))
        return getCommonApiResult(result)
    }

    /**
     *  运转情况 - 获取类型接口
     */
    suspend fun runningSituationGetTypes(id: String = "SCCJYZQKLX"): ApiCallResult<List<RunningSituationType>> {
        val method = "querySJZDBySJZDID"
        val params = JsonObject().apply {
            addProperty("SJZDID", id)
        }

        val result = client.makeCall(method, Gson().toJson(params))

        Logger.d("RunningSituationGetTypes: $result")
        return getApiResult(result, object : TypeToken<List<RunningSituationType>>() {}.type)
    }

    /**
     *  获取计划类型接口
     */
    suspend fun getPlanTypeList(): ApiCallResult<List<RunningSituationType>> {
        return runningSituationGetTypes("SCCJYZQKJHLX")
    }

    /**
     *  校验车号
     */
    suspend fun validateMachineNo(machineNo: String): ApiCallResult<String> {
        val method = "operaCondCheckMachineno"
        val params = JsonObject().apply {
            addProperty("MACHINENO", machineNo)
        }

        val result = client.makeCall(method, Gson().toJson(params))

        Logger.d("ValidateMachineNo: $result")
        return getCommonApiResult(result)
    }

    /**
     *  获取车间列表
     */
    suspend fun getWorkshopItems(): ApiCallResult<List<WorkShopItem>> {
        val method = "toQueryWorkShop"

        val result = client.makeCall(method, "{}")

        Logger.d("toQueryWorkShop $result")
        // 这个接口并没有按照，通用格式返回，特殊处理
        return when (result) {
            is SuccessResult -> {
                ApiCallResult.Success(
                    Gson().fromJson(
                        result.value,
                        object : TypeToken<List<WorkShopItem>>() {}.type
                    )
                )
            }
            is ErrorResult -> {
                ApiCallResult.Error(error = result.error)
            }
        }
    }

    /**
     *  交班记录 / 根据车号获取布号信息
     */
    suspend fun shiftChangeGetClothInfo(machineNo: String): ApiCallResult<List<ShiftChangeClothInfo>> {
        val method = "changeShiftsbyMachineno"
        val params = buildJsonParam { addProperty("MACHINENO", machineNo) }
        val result = client.makeCall(method, params)

        Logger.d("shiftChangeGetClothInfo $result")

        return getApiResult(result, object : TypeToken<List<ShiftChangeClothInfo>>() {}.type)
    }

    /**
     *  交班记录 / 获取原料信息
     */
    suspend fun shiftChangeGetMaterials(groupNo: String): ApiCallResult<List<ShiftChangeMaterial>> {
        val method = "changeShiftsselYlxx"
        val params = buildJsonParam { addProperty("GROUPNO", groupNo) }
        val result = client.makeCall(method, params)

        return getApiResult(result, object : TypeToken<List<ShiftChangeMaterial>>() {}.type)
    }

    /**
     *  交班记录 / 保存
     */
    suspend fun shiftChangeRecordSave(
        id: String,
        account: String,
        list: List<ShiftChangeSaveItem>
    ): ApiCallResult<String> {
        return shiftChangeRecordSaveAdd(id, account,/*保存*/"1", list)
//        val method = "changeShiftsSave"
//        val params = buildJsonParam {
//            addProperty("XTYHID", id)
//            addProperty("XM", account)
//            addProperty("TYPE", "0") // 0 新增，1 保存
//            add("jsonData", Gson().toJsonTree(list))
//        }
//
//        val result = client.makeCall(method, params)
//        return getCommonApiResult(result)
    }

    suspend fun shiftChangeRecordAdd(
        id: String,
        account: String,
        list: List<ShiftChangeSaveItem>
    ): ApiCallResult<String> {
        return shiftChangeRecordSaveAdd(id, account,/*新增*/"0", list)
    }

    private suspend fun shiftChangeRecordSaveAdd(
        id: String,
        account: String,
        type: String,
        list: List<ShiftChangeSaveItem>
    ): ApiCallResult<String> {
        val method = "changeShiftsSave"
        val params = buildJsonParam {
            addProperty("XTYHID", id)
            addProperty("XM", account)
            addProperty("TYPE", type) // 0 新增，1 保存
            add("jsonData", Gson().toJsonTree(list))
        }

        val result = client.makeCall(method, params)
        return getCommonApiResult(result)
    }


    /**
     *  交班记录 / 查询列表
     */
    suspend fun shiftChangeQueryList(
        id: String,
        clothNo: String,
        workshopId: String,
        fromDate: String,
        toDate: String,
        fromMachineNo: String,
        toMachineNo: String
    ): ApiCallResult<List<ShiftChangeQueryItem>> {
        val method = "changeShiftsList"
        val params = buildJsonParam {
            addProperty("XTYHID", id)
            addProperty("LISTDATE_FROM", fromDate)
            addProperty("LISTDATE_TO", toDate)
            addProperty("MACHINENO_FROM", fromMachineNo)
            addProperty("MACHINENO_TO", toMachineNo)
            addProperty("CLOTHNO", clothNo)
            addProperty("BMXXID", workshopId)
        }

        val result = client.makeCall(method, params)

        return getApiResult(result, object : TypeToken<List<ShiftChangeQueryItem>>() {}.type)
    }

    /**
     *  交班记录 / 删除条目
     */
    suspend fun shiftChangeDeleteItem(items: List<String>): ApiCallResult<String> {
        val method = "changeShiftsDel"
        val params = buildJsonParam {
            addProperty("PKIDS", items.joinToString(","))
        }

        val result = client.makeCall(method, params)

        return getCommonApiResult(result)
    }


    private fun buildJsonParam(block: JsonObject.() -> Unit): String {
        val json = JsonObject()
        json.block()
        return if (json.size() == 0) "{}" else Gson().toJson(json)
    }



    /**
     *  纱支盘存明细查询接口
     *  @param date 日期
     *  @param CLOTHTKTNO 三联号
     *  @param type 1 根据三联号查询 2查询按钮查询
     */
    suspend fun querytakeInventoryList(
        id: String,
        date: String?,
        CLOTHTKTNO: String? = null,
        type:Int
    ): ApiCallResult<List<TakeInVentorySave>> {

        val method:String?
        if(type==1){//三联号查询
            method= "monthCheckbyClothtktno"
        }else{//查询按钮
            method= "monthCheckList"
        }
        val params = buildJsonParam {
            if(type==2) {
                addProperty("XTYHID", id)
            }
            addProperty("MONTHDATE", date)
            addProperty("CLOTHTKTNO", CLOTHTKTNO)
        }

        val result = client.makeCall(method, params)

        return getApiResult(result, object : TypeToken<List<TakeInVentorySave>>() {}.type)
    }

    /**
     *  纱支盘存保存
     *  @param account 用户
     *  @param list 保存列表
     */
    suspend fun saveTakeInventory(
        id: String,
        account: String,
        list: List<TakeInVentorySave>
    ): ApiCallResult<String> {
        val method = "monthCheckSave"
        val params = buildJsonParam {
            addProperty("XTYHID", id)
            addProperty("XM", account)
            add("jsonData", Gson().toJsonTree(list))
        }

        val result = client.makeCall(method, params)
        return getCommonApiResult(result)
    }

    /**
     *  纱支盘存删除
     */
    suspend fun deleteTakeInventory(
        id: String,
        account: String,
        list: List<TakeInVentorySave>
    ): ApiCallResult<String> {
        val method = "monthCheckDel"
        val params = buildJsonParam {
            addProperty("XTYHID", id)
            addProperty("XM", account)
            add("jsonData", Gson().toJsonTree(list))
        }

        val result = client.makeCall(method, params)
        return getCommonApiResult(result)
    }

    /**
     *  纱支盘存获取月份
     */
    suspend fun getTakeInventoryMonth(
       ): ApiCallResult<String> {
        val method = "monthCheckMonthdate"

        val result = client.makeCall(method, "")
        return getApiResult(result,object : TypeToken<String>() {}.type)
    }
}